﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.VisionModels;
using thinger.VisitionDAL;

namespace thinger.VisionDemo
{
  
    public class ZmotionEx : Zmotion
    {
        //轴号设置
        public short XAxis = 4;
        public short YAxis = 5;

        public short Z1Axis = 0;
        public short U1Axis = 1;
        public short Z2Axis = 2;
        public short U2Axis = 3;


        //运动速度
        public float XMoveVel = 10.0f;
        public float YMoveVel = 10.0f;
        public float ZMoveVel = 10.0f;
        public float UMoveVel = 100.0f;

        //输入信号
        public short XLimitNeg = 192;
        public short XLimitPos = 193;
        public short YLimitNeg = 208;
        public short YLimitPos = 209;

        public short Z1LimitPos = 0;
        public short Z1LimitNeg = 2;
        public short Z2LimitPos = 1;
        public short Z2LimitNeg = 3;

        //输出信号
        public short GetGY = 0;
        public short PutGY = 2;
        public short DownGY = 1;

        public short Z1Clip = 4;
        public short Z2Clip = 5;

        #region 初始化板卡
        /// <summary>
        /// 初始化板卡
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="isRom"></param>
        /// <param name="timeOut"></param>
        /// <returns></returns>
        public OperateResult InitCard(string fileName, bool isRom, int timeOut = 10000)
        {
            //下载BAS文件
            var result = BasDown(fileName, isRom);

            if (result.IsSuccess)
            {
                IEC_Timer_TON ton = new IEC_Timer_TON(timeOut);
                ton.Input = true;

                int initStatus = -1;

                while (true)
                {
                    initStatus = GetInitStatus();

                    bool completed = initStatus >= 1;

                    bool output = ton.Output;

                    if (completed)
                    {
                        break;
                    }
                    else if (!output)
                    {
                        continue;
                    }
                    else
                    {
                        return OperateResult.CreateFailResult("获取初始化状态超时！");
                    }
                }

                switch (initStatus)
                {
                    //正常结束
                    case 1:
                        return new OperateResult(true, "检测到轴数：" + GetTotalAxisnum());
                    case 2:
                        return OperateResult.CreateFailResult("总线扫描失败");
                    case 3:
                        return OperateResult.CreateFailResult("总线启动失败");
                    default:
                        return OperateResult.CreateFailResult("未知错误原因");
                }
            }
            else
            {
                return result;
            }
        }

        #endregion

        #region 回原点

        public OperateResult ZeroU1()
        {
            return ZeroPos(U1Axis);
        }

        public OperateResult ZeroU2()
        {
            return ZeroPos(U2Axis);
        }

        public OperateResult ZeroZ1()
        {
            var result = DirectZeroAxis(Z1Axis, ZMoveVel, ZMoveVel * 0.1f, Z1LimitNeg, 0.0f, ZMoveVel * 10, ZMoveVel * 10);

            if (result.IsSuccess)
            {
                return WaitHomeStop(Z1Axis);
            }
            return result;
        }

        public OperateResult ZeroZ2()
        {
            var result = DirectZeroAxis(Z2Axis, ZMoveVel, ZMoveVel * 0.1f, Z2LimitNeg, 0.0f, ZMoveVel * 10, ZMoveVel * 10);

            if (result.IsSuccess)
            {
                return WaitHomeStop(Z2Axis);
            }
            return result;
        }

        public OperateResult ZeroX()
        {
            var result = BUSZeroAxis(XAxis, XMoveVel, XMoveVel * 0.1f,0.0f, 17);

            if (result.IsSuccess)
            {
                return WaitBusHomeStop(XAxis);
            }
            return result;
        }


        public OperateResult ZeroY()
        {
            var result = BUSZeroAxis(YAxis, YMoveVel, YMoveVel * 0.1f, 0.0f, 17);

            if (result.IsSuccess)
            {
                return WaitBusHomeStop(YAxis);
            }
            return result;
        }

        public OperateResult ZeroAll()
        { 
            List<Task<OperateResult>> tasks = new List<Task<OperateResult>>();

            tasks.Add(Task.Run(() =>
            {
                if (ZeroZ1().IsSuccess)
                {
                    return ZeroU1();
                }
                else
                {
                    return OperateResult.CreateFailResult();
                }
            }));

            tasks.Add(Task.Run(() =>
            {
                if (ZeroZ2().IsSuccess)
                {
                    return ZeroU2();
                }
                else
                {
                    return OperateResult.CreateFailResult();
                }
            }));

            var result = Task.WhenAll(tasks).GetAwaiter().GetResult();

            //如果任意一个有问题，就直接返回
            foreach (var item in result)
            {
                if (item.IsSuccess == false)
                {
                    return item;
                }
            }

           tasks = new List<Task<OperateResult>>();

            tasks.Add(Task.Run(() =>
            {
                return ZeroX();
            }));

            tasks.Add(Task.Run(() =>
            {
                return ZeroY();
            }));

             result = Task.WhenAll(tasks).GetAwaiter().GetResult();

            //如果任意一个有问题，就直接返回
            foreach (var item in result)
            {
                if (item.IsSuccess == false)
                {
                    return item;
                }
            }

            return OperateResult.CreateSuccessResult();
        }

        #endregion

        #region 移动封装
        public OperateResult MoveXY(float x, float y)
        {
            return MoveLineAbs(new int[] { XAxis, YAxis }, new float[] { x, y }, XMoveVel, XMoveVel * 10, XMoveVel * 10);
        }

        public OperateResult MoveXYRelative(float x, float y)
        {
            return MoveLineRelative(new int[] { XAxis, YAxis }, new float[] { x, y }, XMoveVel, XMoveVel * 10, XMoveVel * 10);
        }

        public OperateResult MoveZ1(float z)
        {
            return MoveAbs(Z1Axis, ZMoveVel, z, 0.0f, ZMoveVel * 10, ZMoveVel * 10, 100);
        }
        public OperateResult MoveZ2(float z)
        {
            return MoveAbs(Z2Axis, ZMoveVel, z, 0.0f, ZMoveVel * 10, ZMoveVel * 10, 100);
        }
        #endregion

        #region 气源控制

        /// <summary>
        /// Z1电磁阀
        /// </summary>
        /// <returns></returns>
        public bool Z1ClipState()
        {
            return GetOutput(Z1Clip);
        }

        public OperateResult XQZ1()
        {
            return SetOutput(Z1Clip, true);
        }
        public OperateResult FQZ1()
        {
            return SetOutput(Z1Clip, false);
        }
        public bool Z2ClipState()
        {
            return GetOutput(Z2Clip);
        }

        public OperateResult XQZ2()
        {
            return SetOutput(Z2Clip, true);
        }
        public OperateResult FQZ2()
        {
            return SetOutput(Z2Clip, false);
        }

        #endregion

        #region 光源控制

        public bool GetGYState()
        {
            return GetOutput(GetGY);
        }

        public OperateResult GetGYOpen()
        {
            return SetOutput(GetGY, true);
        }

        public OperateResult GetGYClose()
        {
            return SetOutput(GetGY, false);
        }

        public bool PutGYState()
        {
            return GetOutput(PutGY);
        }

        public OperateResult PutGYOpen()
        {
            return SetOutput(PutGY, true);
        }

        public OperateResult PutGYClose()
        {
            return SetOutput(PutGY, false);
        }

        public bool DownGYState()
        {
            return GetOutput(DownGY);
        }


        public OperateResult DownGYOpen()
        {
            return SetOutput(DownGY, true);
        }

        public OperateResult DownGYClose()
        {
            return SetOutput(DownGY, false);
        }

        #endregion

        #region 伺服使能

        public bool GetXAxisEnable()
        {
            return GetEnable(XAxis);
        }

        public bool GetYAxisEnable()
        {
            return GetEnable(YAxis);
        }

        public OperateResult SetXAxisEnable(bool enable)
        {
            return SetEnable(XAxis, enable);
        }

        public OperateResult SetYAxisEnable(bool enable)
        {
            return SetEnable(YAxis, enable);
        }

        #endregion

        #region  获取限位信号
        public bool GetXLimitPos()
        {
            return GetInput(XLimitPos);
        }

        public bool GetXLimitNeg()
        {
            return GetInput(XLimitNeg);
        }

        public bool GetYLimitPos()
        {
            return GetInput(YLimitPos);
        }

        public bool GetYLimitNeg()
        {
            return GetInput(YLimitNeg);
        }

        public bool GetZ1LimitPos()
        {
            return GetInput(Z1LimitPos);
        }

        public bool GetZ1LimitNeg()
        {
            return GetInput(Z1LimitNeg);
        }

        public bool GetZ2LimitPos()
        {
            return GetInput(Z2LimitPos);
        }

        public bool GetZ2LimitNeg()
        {
            return GetInput(Z2LimitNeg);
        }

        #endregion

        #region 获取实时位置

        public  string GetXPos()
        {
            return "X轴：" + GetPos(XAxis).ToString("f2") + " mm";
        }

        public string GetYPos()
        {
            return "Y轴：" + GetPos(YAxis).ToString("f2") + " mm";
        }
        public string GetZ1Pos()
        {
            return "Z1轴：" + GetPos(Z1Axis).ToString("f2") + " mm";
        }

        public string GetU1Pos()
        {
            return "U1轴：" + GetPos(U1Axis).ToString("f2") + " °";
        }
        public string GetZ2Pos()
        {
            return "Z2轴：" + GetPos(Z2Axis).ToString("f2") + " mm";
        }

        public string GetU2Pos()
        {
            return "U2轴：" + GetPos(U2Axis).ToString("f2") + " mm";
        }

        #endregion
    }
}
